package com.sap.health.tracker;

import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONObject;


import com.androidplot.xy.XYPlot;
import com.google.android.gcm.GCMRegistrar;
import com.sap.health.tracker.animation.CollapseAnimation;
import com.sap.health.tracker.animation.ExpandAnimation;

import com.sap.health.tracker.json.JSONFunctions;
import com.sap.health.tracker.library.StoreData;
import com.sap.health.tracker.threads.ConnectionsThread;
import com.sap.health.tracker.threads.LogThread;
import com.sap.health.tracker.threads.ProfileThread;
import com.sap.health.tracker.threads.HospitalsThread;
import com.sap.health.tracker.threads.NotificationsThread;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.support.v4.app.FragmentActivity;
import android.util.DisplayMetrics;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

/*
 * This is the main class that controls everything in the app.
 */
public class Main extends FragmentActivity implements 
		AdapterView.OnItemSelectedListener {
    
    private static Context sctx;
    // JSON Response node names
    private static String KEY_SUCCESS = "success";
    private static String KEY_UID = "uid";
    private static String KEY_SESSION = "session";
    private static String KEY_ROLE = "role";

    //progress dialog
	private ProgressDialog mLoadingDialog;
	// the side menu
	private LinearLayout mMenuList;
	// toggles the side menu
	private Button mBtnToggleMenuList;
	//screen width
	private int mScreenWidth;
	// whether the menu is showing or not
	private boolean mIsExpanded;
	// profile button in the menu
	private TableRow mProfileBtn;
	//connections button in the menu
	private TableRow mConnectionsBtn;
	// the logs button in the menu
	private TableRow mLogBtn;
	// the notifications button in the menu.
	private TableRow mNotBtn;
	// the calendar button in the menu.
	private TableRow mCalBtn;
	//the logout button in the menu.
	private TableRow mLogoutBtn;
	// the hospital button in the menu.
	private TableRow mHsptBtn;
	//the doctors button in the menu.
	private TableRow mDoctorsBtn;
	// the plus button on the action bar.
	private ImageView mPlus;
    // navigation spinner for log data.
    private Spinner mLogNav;
    // user id attached to the user.
	private String userId = "";
	// session token connected with the user and device.
	private String session = "";
	// used for storing data locally.
	private StoreData store;
	// the current view we are in - used for changing views.
	private static int currentView;
    // array for storing navigation names.
	private ArrayList<String> mNavArray = new ArrayList<String>();
	// global so we can make it disappear.
    private Spinner mGraphLogTypeSpin;

    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // stops soft keyboard from popping up without the user clicking.
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.
        		SOFT_INPUT_STATE_ALWAYS_HIDDEN); 

        // set to main layout.
        setContentView(R.layout.main_layout);       
        sctx = this;       
        // get data from local storage.
        store = new StoreData();
        // get user id from local storage
        userId = (String) store.openType(sctx, String.class, KEY_UID);
        // get session token from local storage
        session = (String) store.openType(sctx, String.class, KEY_SESSION);
        // get the role the user is.
        String role = (String) store.openType(sctx, String.class, KEY_ROLE);  
        
        // if this is the first since installing the app, give help message.
        if(!"completed".equals(store.openType(sctx, String.class, "help"))){           
        	helpDialog("If you are having problems with anything and need help," 
        			+ " try long clicking on the item in question to see if " +
        					"there is a help message.");
        	// the user has seen the message, no need to show it again.
        	store.saveType(sctx, String.class, "help", "completed");
        }
        // setup the layout.
        startupLayoutSetup();
        // setup up the side menu slider.
        toggleSideMenuSetup();
        // setup the menus.
        sideMenuBtnSetup(role);
 	   	// go to notifications page by default.
        notificationsSetup();  
        // setup the GCM message system (push notifications).
        new GCMNotifications(sctx);
        
    }
    /*
     * Setup the main layout.
     */
    private void startupLayoutSetup(){   	  
    	// swap left template menu with menu.xml
    	currentView = R.id.tempLeftMenu;
    	switchView(R.layout.menu, "Views");   
    	// swap template tempLayout with layout main_profile.xml        
    	currentView = R.id.tempLayout;	   
    	// find the leftMenu id in layout menu.xml
    	mMenuList = (LinearLayout) findViewById(R.id.leftMenu);
    	mBtnToggleMenuList = (Button) findViewById(R.id.menuBtn);
    	// on long click, display help dialog.
    	mBtnToggleMenuList.setOnLongClickListener(new OnLongClickListener() { 
    		@Override
    		public boolean onLongClick(View v) {
    			helpDialog("This is the options menu. Here you will be able to " +
    					"access the different features of the app.");               	                	
    			return true;
    		}
    	});  
    	//Navigation spinner used for log data.
    	mLogNav = (Spinner) findViewById(R.id.nav);
    	// Make sure menu is closed to begin with
    	LayoutParams lyp =  mMenuList.getLayoutParams();
    	lyp.width = 1;   
    	// get the plus button.
    	mPlus = (ImageView) findViewById(R.id.plus);
    	// on long click, show help dialog.
    	mPlus.setOnLongClickListener(new OnLongClickListener() { 
    		@Override
    		public boolean onLongClick(View v) {
    			helpDialog("Depending on the layout you are currently in, " +
    					"you will be able to add things such as logs and " +
    					"calendars events.");               	                	
    			return true;
    		}
    	});	   
    } 
    /*
     *  This is the setup for the side menu, sets up the buttons.
     */
    private void sideMenuBtnSetup(String role){
    	// check if the user is a patient. 	
    	if(role.equalsIgnoreCase("patient")){      
    		mLogBtn = (TableRow) findViewById(R.id.logBtn); 
    		mLogBtn.setOnClickListener(new View.OnClickListener() {
    			public void onClick(View v) {
    				// setup the log data layout.
    				logDataSetup();
                }
            });
    		// on long click, show the help dialog.
    		mLogBtn.setOnLongClickListener(new OnLongClickListener() { 
    			@Override
                public boolean onLongClick(View v) {
    				helpDialog("This is where you can log your data." +
                    		"\n\n" +
                    		"Log History is where you can view and add " +
                    		"specific logs that can be benchmarked with " +
                    		"others. To benchmark, click the Compare option " +
                    		"in the drop down menu." +
                    		"\n\n" +
                    		"Symptoms is where you can log your own data " +
                    		"that is related to an illness or a symptom " +
                    		"that you feel needs to be logged." +
                    		"\n\n" + 
                    		"Food log allows you to log the food you eat." + 
                    		"\n\n" +
                    		"Graph lets you view your log history in graph " +
                    		"form." +
                    		"\n\n" +
                    		"Compare allows you to compare your log data " +
                    		"with others. NOTE: The values that are taken " +
                    		"are the average per day.");               	                	
                    return true;
                }
            });
    	} else {		// user is a doctor, hide the log data button.
    		mLogBtn = (TableRow) findViewById(R.id.logBtn); 
            mLogBtn.setVisibility(View.GONE);
    	}   	
    	mDoctorsBtn = (TableRow) findViewById(R.id.doctorsBtn); 
    	mDoctorsBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	mLogNav.setVisibility(View.INVISIBLE);
                doctorsSetup();
            }
        });
        // on long click, show the help dialog.
    	mDoctorsBtn.setOnLongClickListener(new OnLongClickListener() { 
            @Override
            public boolean onLongClick(View v) {
                helpDialog("Here you can view all the registered Doctors." +
                		"\n\n" +
                		"If you are a patient, you can connect with a Doctor " +
                		"and they will be able to view your log data to " +
                		"see how you are progressing." +
                		"\n\n" +
                		"You are also able to search for a Doctor or the " +
                		"hosptial they are associated with.");               	                	
                return true;
            }
        });
    	
        mConnectionsBtn = (TableRow) findViewById(R.id.connectionsBtn); 
        mConnectionsBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	mLogNav.setVisibility(View.INVISIBLE);
            	connectionsSetup();
            }
        });
        // on long click, show the help dialog.
        mConnectionsBtn.setOnLongClickListener(new OnLongClickListener() { 
             @Override
             public boolean onLongClick(View v) {
                 helpDialog("This is where you can see the people you are " +
                 		"connected with. " +
                 		"\n\n" +
                 		"If you are a Patient, you will be able to see the " +
                 		"Doctors that you are connected with." +
                 		"\n\n" +
                 		"If you are a Doctor, you will be able to see the " +
                 		"Patients that you are connected with." +
                 		"\n\n" +
                 		"NOTE: Only Patients are able to request a connection "+
                 		"to a Doctor. Doctors and Patients are able to " +
                 		"remove connections.");               	                	            
                 return true;
             }
        });  	
    	mProfileBtn = (TableRow) findViewById(R.id.profileBtn); 
    	mProfileBtn.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
            	 mLogNav.setVisibility(View.INVISIBLE);
            	 profileSetup();          	
             }
        });  
        // on long click, show the help dialog.
    	mProfileBtn.setOnLongClickListener(new OnLongClickListener() { 
             @Override
             public boolean onLongClick(View v) {
                 helpDialog("Here you are able to view and edit your profile.");               	                	             
                 return true;
             }
        });        
    	mHsptBtn = (TableRow) findViewById(R.id.hsptBtn); 
         mHsptBtn.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
            	 mLogNav.setVisibility(View.INVISIBLE);
            	 hsptSetup();          	
             }
         }); 
         // on long click, show the help dialog.
         mHsptBtn.setOnLongClickListener(new OnLongClickListener() { 
             @Override
             public boolean onLongClick(View v) {
                 helpDialog("This is where you can view registered hospitals.");               	                	
                 
                 return true;
             }
         });              
         mNotBtn = (TableRow) findViewById(R.id.notBtn); 
         mNotBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	mLogNav.setVisibility(View.INVISIBLE);
            	notificationsSetup();
            }
        });
         // on long click, show the help dialog.
        mNotBtn.setOnLongClickListener(new OnLongClickListener() { 
        	@Override
            public boolean onLongClick(View v) {
                helpDialog("Here you will be able to view your notifications.");               	                	               
                return true;
            }
        });        
        mCalBtn = (TableRow) findViewById(R.id.calBtn); 
        mCalBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	mLogNav.setVisibility(View.INVISIBLE);
            	calendarSetup();
            }
        });
        // on long click, show the help dialog.
        mCalBtn.setOnLongClickListener(new OnLongClickListener() { 
            @Override
            public boolean onLongClick(View v) {
                helpDialog("This is where you can access your calendars." +
                		"\n\n" +
                		"NOTE: If you wish to view your calendar that was " +
                		"created through the website, you will have to switch "+
                		"to it manually through the calendar app.");               	                	              
                return true;
            }
        });        
        mLogoutBtn = (TableRow) findViewById(R.id.optBtn); 
        mLogoutBtn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	mLogNav.setVisibility(View.INVISIBLE);
            	logout();
            }
        });
        // on long click, show the help dialog. 
        mLogoutBtn.setOnLongClickListener(new OnLongClickListener() { 
            @Override
            public boolean onLongClick(View v) {
                helpDialog("This will log you out from the app." +
                		"\n\n" +
                		"NOTE: There is no personal data stored on the phone " +
                		"at any time.");               	                	               
                return true;
            }
        });       
    }
    /*
     * Open and close the side menu.
     */
    private void toggleSideMenuSetup(){
        DisplayMetrics metrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metrics);
        mScreenWidth = metrics.widthPixels;
        mBtnToggleMenuList.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {
        		// if it's open, then close it, otherwise, open it.
        		if (mIsExpanded) {
        			mIsExpanded = false;
        			mMenuList.startAnimation(new CollapseAnimation(mMenuList, 
        					0,(int)(mScreenWidth*0.7), 20));
        		}else {
        			mIsExpanded = true;
            		mMenuList.startAnimation(new ExpandAnimation(mMenuList, 
            				0,(int)(mScreenWidth*0.7), 20));
        		}
        	}
        });       
    }
    
    /*
     * Switch the current view with the one that's specified.
     */
    public static void switchView(int optionId, String toggleName){
    	// get the current view.
    	View Current = (View) ((Activity) sctx).findViewById(currentView);
        // change the name on the toggle button.
        Button toggle = (Button) ((Activity)sctx).findViewById(R.id.menuBtn);
        toggle.setText(toggleName);
        // get the parent view
        ViewGroup parent = (ViewGroup) Current.getParent();
        int index = parent.indexOfChild(Current);
        // remove current view
        parent.removeView(Current);
        // create new current view
        Current = (View) ((Activity) sctx).getLayoutInflater().inflate(optionId,
        		parent, false);
        // add to parent.
        parent.addView(Current, index);
    }    
    /*
     * This sets up the view doctors layout.
     */
    private void doctorsSetup(){   	
    	// hide the plus button
    	mPlus.setVisibility(View.GONE);    	
    	// Close side menu
        mIsExpanded = false;
    	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
    			(int)(mScreenWidth*0.7), 20));   	
		// Swap content layout	
    	switchView(R.layout.main_content, "Doctors");
    	currentView = R.id.contentView;
    	// get layout assets for the layout.
        TextView getErrorMsg = (TextView) findViewById(R.id.error_text);
        EditText searchInput = (EditText) findViewById(R.id.searchText);
        LinearLayout searchLayout = 
        	(LinearLayout) findViewById(R.id.searchLayout);      
        // show the search bar.
        searchLayout.setVisibility(View.VISIBLE);       
        Button search = (Button) findViewById(R.id.search);
        // main table content.
   	 	TableLayout connectionTable = 
   	 		(TableLayout)findViewById(R.id.contentTable);    	
        ImageView refresh = (ImageView) findViewById(R.id.refresh);
        // create new connections class.
        ConnectionsThread connectionsThread = 
        	new ConnectionsThread(sctx, userId, session, getErrorMsg, 
        			connectionTable, refresh, "doctors", searchInput, search);
   	 	// call doctors function.
        connectionsThread.getDoctors();   	
    }
    /*
     * Set up the layout for the connections that users are connected with.
     */
    private void connectionsSetup(){ 	
    	// hide the plus button
    	mPlus.setVisibility(View.GONE); 	
    	// Close side menu
        mIsExpanded = false;
    	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
    			(int)(mScreenWidth*0.7), 20));			
		// Swap content layout	
    	switchView(R.layout.main_content, "Connections");
    	currentView = R.id.contentView;
    	// get layout assets.
        TextView getErrorMsg = (TextView) findViewById(R.id.error_text);    
        EditText searchInput = (EditText) findViewById(R.id.searchText);
        // hide search bar.
        LinearLayout searchLayout = 
        	(LinearLayout) findViewById(R.id.searchLayout);      
        searchLayout.setVisibility(View.GONE);     
        Button search = (Button) findViewById(R.id.search);
        // main content table.
   	 	TableLayout connectionTable = 
   	 		(TableLayout)findViewById(R.id.contentTable);    	
        ImageView refresh = (ImageView) findViewById(R.id.refresh);
        // new conections class
    	ConnectionsThread connectionsThread = 
    		new ConnectionsThread(sctx, userId, session,
    			getErrorMsg, connectionTable, refresh, "connections", 
    			searchInput, search);
   	 	// call connections function.
    	connectionsThread.getConnections();
    }
    /*
     * Set up the log data layout.
     */
    private void logDataSetup(){
    	// show the log navigation spinner.
    	mLogNav.setVisibility(View.VISIBLE);
    	mLogNav.setOnItemSelectedListener(this);
	    // clear array to make sure we don't duplicate.
    	mNavArray.clear();
    	// add names to array.
    	mNavArray.add("Log History");
    	mNavArray.add("Symptom");
    	mNavArray.add("Food");
    	mNavArray.add("Graph");
    	mNavArray.add("Compare");
        // create array adaptor and add names to it.
        ArrayAdapter<String> navAdapter = new ArrayAdapter<String>(sctx,
	    		android.R.layout.simple_spinner_item, mNavArray);  	    
	    // Specify the layout to use when the list of choices appears
        navAdapter.setDropDownViewResource(
        		android.R.layout.simple_spinner_dropdown_item);    
	    // Apply the adapter to the spinner
        mLogNav.setAdapter(navAdapter);       
        /***
         * 
         * TAKE NOTE!!
         * The Spinner runs the first item in the list by default.
         * 
         ******/        
    }
    /*
     * Setup the layout for symptoms.
     */
    private void symptomSetup(){   	
    	// Close side menu
    	mIsExpanded = false;
    	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
    			(int)(mScreenWidth*0.7), 20));  	   	     
    	// Swap content layout
    	switchView(R.layout.main_content, "Log");
    	currentView = R.id.contentView;
    	// get layout ssests.
        TextView getLogErrorMsg = (TextView) findViewById(R.id.error_text);
        TableLayout logTable = (TableLayout) findViewById(R.id.contentTable);      
    	ImageView refresh = (ImageView) findViewById(R.id.refresh);
    	// create new log class.
        final LogThread logThread = new LogThread(sctx, userId, session,
    			refresh);
        // get the log type spinner.
    	Spinner logTypeSpin = (Spinner) findViewById(R.id.contentSpinner);
    	// call symptpoms setup function.
    	logThread.symptomSetup(getLogErrorMsg, logTable, logTypeSpin);
    	// show the plus button.
    	mPlus.setVisibility(View.VISIBLE);
    	mPlus.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {
        		logThread.addSymptomSetup();
        	}
        });     
    }
    /*
     * Setup the log history layout.
     */
    private void logHistorySetup(){    	
    	// Close side menu
    	mIsExpanded = false;
    	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
    			(int)(mScreenWidth*0.7), 20));  	  	     
    	// Swap content layout
    	switchView(R.layout.main_content, "Log");
    	currentView = R.id.contentView;
    	// get layout assets.
        TextView getLogErrorMsg = (TextView) findViewById(R.id.error_text);
        TableLayout logTable = (TableLayout) findViewById(R.id.contentTable);       	
    	ImageView refresh = (ImageView) findViewById(R.id.refresh);
    	Spinner logTypeSpin = (Spinner) findViewById(R.id.contentSpinner);
    	// new log class.
    	final LogThread logThread = new LogThread(sctx, userId, session,
    			refresh);
    	//call log history function.
    	logThread.logHistorySetup(getLogErrorMsg, logTable, logTypeSpin);
    	// show plus button.
    	mPlus.setVisibility(View.VISIBLE);
    	mPlus.setOnClickListener(new OnClickListener() {
    		public void onClick(View v) {
    			// add a new log.
    			logThread.addLogSetup();        	
        	}
        });
    }
    /*
     *  Setup the food layout.
     */
    private void foodSetup(){    	
    	// Close side menu
    	mIsExpanded = false;
    	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
    			(int)(mScreenWidth*0.7), 20));  	  	     
    	// Swap content layout
    	switchView(R.layout.main_content, "Log");
    	currentView = R.id.contentView;
    	// get layout assets.
        TextView getLogErrorMsg = (TextView) findViewById(R.id.error_text);
        TableLayout logTable = (TableLayout) findViewById(R.id.contentTable);       	
    	ImageView refresh = (ImageView) findViewById(R.id.refresh);
    	Spinner logTypeSpin = (Spinner) findViewById(R.id.contentSpinner);
    	// new log class.
    	final LogThread logThread = new LogThread(sctx, userId, session,
    			refresh);
    	// call food setup function.
    	logThread.logFoodSetup(getLogErrorMsg, logTable, logTypeSpin);
    	// show plus button.
    	mPlus.setVisibility(View.VISIBLE);
    	mPlus.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {
        		// add food setup.
        		logThread.addFoodSetup();        
        	}
        });
    }
    /*
     * Setup compare layout. 
     */
    private void compareSetup(){
    	// Swap content layout
    	switchView(R.layout.log_compare, "Log");
    	currentView = R.id.logdataView;
    	// get layout assets
        Spinner logTypeSpin = (Spinner) findViewById(R.id.logsTypeSpinner);
        TextView getLogErrorMsg = (TextView) findViewById(R.id.error_text);
        TableLayout logTable = (TableLayout) findViewById(R.id.contentTable);
        TableLayout valueTable = (TableLayout) findViewById(R.id.value);
        TableLayout comparisonTable = 
        	(TableLayout) findViewById(R.id.comparison);
        TableLayout dateTable = (TableLayout) findViewById(R.id.date);
        TableLayout allTable = (TableLayout) findViewById(R.id.allTable);      
    	ImageView refresh = (ImageView) findViewById(R.id.refresh);
        // new log class.
        LogThread logThread = new LogThread(sctx, userId, session,
    			refresh);
        // call compare setup.
        logThread.compareSetup(getLogErrorMsg, logTable, logTypeSpin, 
        		valueTable, comparisonTable, dateTable, allTable);       
    }
    /*
     * Setup the graph.
     */
    private void graphSetup(){  	
    	// hide the plus button
    	mPlus.setVisibility(View.GONE);
    	// Swap content layout
    	switchView(R.layout.graph, "Log");
    	currentView = R.id.graphLayout;
    	// get layout assets.      
    	XYPlot graphLayout = (XYPlot) findViewById(R.id.graphLayout);
    	ImageView refresh = (ImageView) findViewById(R.id.refresh);
    	mGraphLogTypeSpin = (Spinner) findViewById(R.id.graphTypes);
    	// new log class.
    	LogThread logThread = new LogThread(sctx, userId, session,
    			refresh);
    	// call graph function.
    	logThread.logGraphSetup(graphLayout, mGraphLogTypeSpin);
    }
    /*
     * When a spinner item is selected when in the log layout, run the correct
     * function for it.
     */
    public void onItemSelected(AdapterView<?> parent, View view, 
            int pos, long id) {
    	// make sure it's not null before removing it.
    	if(mGraphLogTypeSpin != null){
    		mGraphLogTypeSpin.setVisibility(View.GONE);
    	}
    	// make sure we have the right spinner.
    	if (parent == mLogNav){    		
    		switch (pos){
            case 0:
            	logHistorySetup();
            	break;
            case 1:
            	symptomSetup();
            	break;
            case 2:
            	foodSetup();
            	break;
            case 3: 
            	graphSetup();
            	break;
            case 4:
            	compareSetup();
            	break;
            default:
            	logHistorySetup();    
        		break;
            }
    	}
    }
    /*
     * Setup for hospital layout.
     */
    private void hsptSetup(){ 	
    	// hide the plus button
    	mPlus.setVisibility(View.GONE);  	
    	// Close side menu
        mIsExpanded = false;
     	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
     			(int)(mScreenWidth*0.7), 20));
     	// Swap content layout
		switchView(R.layout.hospital, "Hospitals");
     	currentView = R.id.hospitalsView;
    	// get layout assets.
        TextView getHospitalErrorMsg = (TextView) findViewById(R.id.error_text);
        TableLayout hospitals = (TableLayout) findViewById(R.id.hospitalsTable);    
        ImageView refresh = (ImageView) findViewById(R.id.refresh);
     	// create new hospital class.
     	HospitalsThread hospitalsThread = new HospitalsThread(sctx, userId, 
     			session, getHospitalErrorMsg, hospitals, refresh);
     	// call hospital function.
     	hospitalsThread.getHospitals();
    }
    /*
     * Setup the profile layout.
     */
    private void profileSetup(){   	
    	// hide the plus button
    	mPlus.setVisibility(View.GONE);  	
    	// Close side menu
        mIsExpanded = false;
     	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
     			(int)(mScreenWidth*0.7), 20));
     	// Swap content layout
		switchView(R.layout.main_content, "Profile");
     	currentView = R.id.contentView;
    	// get layout assets
        TextView getProfileErrorMsg = (TextView) findViewById(R.id.error_text);
        TableLayout table = (TableLayout) findViewById(R.id.contentTable);    
        ImageView refresh = (ImageView) findViewById(R.id.refresh);
     	// create new profile class.
     	ProfileThread profileThread = new ProfileThread(sctx, userId, session,
     			getProfileErrorMsg, refresh, table);
     	//call profile function. 
     	profileThread.getProfile();   	
    }
    /*
     * Setup the calendar 
     */
    private void calendarSetup(){
    	// Close side menu
    	mIsExpanded = false;
     	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
     			(int)(mScreenWidth*0.7), 20));
     	// Swap content layout
		switchView(R.layout.main_calendar, "Calendar");
     	currentView = R.id.calendarGrid;   
     	// get layout assets.
     	LinearLayout calendarBtn = (LinearLayout)findViewById(R.id.calendarBtn);
     	calendarBtn.setOnClickListener(new OnClickListener() {
     		public void onClick(View v) {
     			try {
     				// get package manager.
             		PackageManager pm = getPackageManager();
             		//find the intent for the stock calendar app.
             		Intent intent = pm.getLaunchIntentForPackage(
             				"com.android.calendar");
             		startActivity(intent);
             		
             	} catch (Exception e){
             		//TODO catch non generic exceptions.
             		System.out.println("Calendar: " + e);
             		helpDialog("No calendar app installed.");
             	}
         	}
     	});
     	// on long click, show help dialog.
     	calendarBtn.setOnLongClickListener(new OnLongClickListener() { 
            @Override
            public boolean onLongClick(View v) {
                helpDialog("Calendars allows you to keep track of certain " +
                		"logs, make appointments with Doctors and " +
                		"set reminders for yourself.\n\n" +
                		"Your stock calendar app " +
                		"will be used and will require access." +
                		"\n\n" +
                		"NOTE: If you wish to view your calendar that was " +
                		"created through the website, you will have to " +
                		"switch to it manually through the calendar app.");               	                	
                return true;
            }
        });
     	// show plus button.
     	mPlus.setVisibility(View.VISIBLE);
     	mPlus.setOnClickListener(new OnClickListener() {
         	public void onClick(View v) {
         		Intent intent = new Intent(Intent.ACTION_INSERT);
         		intent.setData(CalendarContract.Events.CONTENT_URI);
         		startActivity(intent); 
         	}
         });   	
    }
    /*
     * Notifications layout setup.
     */
    private  void notificationsSetup(){   	
    	// hide the plus button
    	mPlus.setVisibility(View.GONE);   	
    	// Close side menu
        mIsExpanded = false;
    	mMenuList.startAnimation(new CollapseAnimation(mMenuList, 0,
    			(int)(mScreenWidth*0.7), 20));
    	// Swap content layout
    	switchView(R.layout.main_content, "Notifications");
    	currentView = R.id.contentView;	
    	// get layout assets.
    	TextView getNotificationsErrorMsg = 
    		(TextView)findViewById(R.id.error_text);
    	TableLayout notifications =(TableLayout)findViewById(R.id.contentTable);    
        ImageView refresh = (ImageView) findViewById(R.id.refresh);
        // create new notifications class.
        NotificationsThread notificationsThread = new NotificationsThread(sctx, 
     			userId, session, getNotificationsErrorMsg, 
     			notifications, refresh);
        //call notifications function.
     	notificationsThread.getNotifications();
    } 
    
    /*
     * Removes all login session data from the server
     */
    public void logout(){
    	// run server connection on different thread.
    	new Thread(new Runnable() {
            @Override
            public void run() {
            	// show progress dialog.
            	createProgressDialog(); 
            	// Check login status in database
            	JSONFunctions jsonFunctions = new JSONFunctions();          	
                //check if local session is stored.
                if(userId != null || userId != "" || session != null || session != ""){     	        
                	// get GCM id.
                	final String regId = GCMRegistrar.getRegistrationId(sctx);
                	// connect to server and remove session data.
                	JSONObject json = jsonFunctions.logOutUser(userId, session, regId);
                	// check for login response
        	        try {
        	             if (json.getString(KEY_SUCCESS) != null) {   	             	
        	             	String res = json.getString(KEY_SUCCESS);
        	                if(Integer.parseInt(res) == 1){  	
        	                	// destroy server session success.
        	                	// create local storage connection.
        	                	runOnUiThread(new Runnable() {
        	            			public void run() {	
		        	                	StoreData store = new StoreData();	        	                	
		        	                    if(store.deleteType(sctx, KEY_UID) == false 
		        	                			|| store.deleteType(sctx, KEY_SESSION) == false){
		        	                		// create alert dialog and tell them there was an error.
		        	                    	simpleDialog("There was an error logging out. If this " +
		        	                    			"message persists, please wipe the app data via the " +
		        	                    			"system settings");       	
		        	                    	// dismiss the progress dialog.
		        	                    	dismissProgressDialog();       	                    	
		        	                	} else { 	
		        	            	    	// Logout successful, switch to login screen.
		        	            	        Intent login = new Intent(getApplicationContext(), 
		        	            	        		LoginActivity.class);
		        	            	        login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		        	            	        startActivity(login);
		        	            	        // Closing current screen
		        	            	        finish();
		        	                	}
        	            			}
        	                	});
        	                }
        	             }
        	         } catch (JSONException e) {
        	        	 //TODO better exception handling.
        	        	 simpleDialog("There was an error logging out. If this " +
        	                    			"message persists, please wipe the app data via the " +
        	                    			"system settings");       	
        	             // dismiss the progress dialog.
        	             dismissProgressDialog();
        	             e.printStackTrace();
        	         }
                } 
            }
    	}).start();
    }
    /**
     * Dismiss progress dialog.
     */
    private void dismissProgressDialog(){
    	runOnUiThread(new Runnable() {
            public void run() {
            	// hide progress spinner now that thread is finished.
            	//loadingSpinner.setVisibility(View.INVISIBLE);
            	mLoadingDialog.dismiss();
            }
        });
    }
    /**
     * Create progress dialog.
     */
    private void createProgressDialog(){
    	runOnUiThread(new Runnable() {
            public void run() {
            	// show progress spinner to let the user know it's working.
            	//loadingSpinner.setVisibility(View.VISIBLE);
            	mLoadingDialog = new ProgressDialog(sctx);
                mLoadingDialog.setTitle("");
                mLoadingDialog.setMessage("Loading. Please wait...");
                mLoadingDialog.show();
            }
        });
    } 
    /**
     * Simple dialog.
     * @param title
     */
    private void simpleDialog(final String title){
    	runOnUiThread(new Runnable() {
			public void run() {
				// custom dialog
				final Dialog dialog = new Dialog(sctx);
				dialog.setContentView(R.layout.popup);
				dialog.setTitle(title);		 	
				Button dialogButton = (Button) dialog.findViewById(R.id.dismiss);
				// if button is clicked, close the custom dialog
				dialogButton.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						dialog.dismiss();
					}
				});		 
				dialog.show();
			}
		}); 		
	}
    /*
     * These are called on phones that have a menu buton.
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item){
    	switch(item.getItemId()){
	    	case R.id.logout:
	    		logout();
	       		break;
	       	case R.id.help:
	       		helpDialog("If you are having problems with anything and " +
       					"need help, try long clicking on the item in " +
       					"question to see if there is a help message.");
	       		break;
	       	default:
       			helpDialog("If you are having problems with anything and " +
       					"need help, try long clicking on the item in " +
       					"question to see if there is a help message.");
	       		break;
	  	}
	  	return true;
    }
    /**
     * Shows a dialog given the help message.
     * @param message
     */
    private void helpDialog(final String message){    	
		// create new dialog
		final Dialog dialog = new Dialog(sctx);
		// assign layout to dialog
		dialog.setContentView(R.layout.popup);
		dialog.setTitle("Help Options");
		// create a row to add text to.
		TableRow noteRow = new TableRow(sctx);
      	// create text view.
      	TextView noteTx = new TextView(sctx);
      	noteTx.setText(message);
      	// make message wrap to next line.
      	noteTx.setLayoutParams(new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1f));           	 
      	// add views to the row
      	noteRow.addView(noteTx);   	 
      	noteRow.setPadding(10, 10, 0, 10);   
      	TableLayout dialogTable = (TableLayout) dialog.findViewById(R.id.dialogTable);    
      	 // add the row to the table layout
      	dialogTable.addView(noteRow);		
      	// button for dismissing the dialog.
		Button dialogButton = (Button) dialog.findViewById(R.id.dismiss);
		// if button is clicked, close the custom dialog
		dialogButton.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dialog.dismiss();
			}
		});
		// show the dialog.
		dialog.show();	
	}

	@Override
	public void onNothingSelected(AdapterView<?> arg0) {
		// This method is not used, but still needed.		
	}
}
